package com.basic.business.common.shiro;

import com.alibaba.fastjson.JSON;
import com.basic.business.common.execption.AuthException;
import com.basic.business.model.entity.SysUser;
import com.basic.business.service.LoginService;
import com.basic.business.service.SysMenuService;
import com.basic.business.service.SysRoleService;
import com.basic.business.utils.IdGenerator;
import com.basic.business.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.springframework.beans.factory.annotation.Autowired;
import static com.basic.business.common.constant.ResultMsgEnum.LOGIN_PWD_ERROR;

/**
 * 当前 Realm 只处理登录请求
 */
@Slf4j
public class LoginRealm extends AbstractRealm {
    @Autowired
    private LoginService loginService;

    @Autowired
    private SysRoleService sysRoleService;

    @Autowired
    private SysMenuService sysMenuService;

    @Autowired
    private RedisUtil redisUtil;

    public static final String SYMBOL_UNDERLINE = "_";
    public static final String REDIS_PROJECT_PREFIX = "HUAGE_BASIC_";
    public static final String REDIS_KEY_PREFIX_LOGIN_ACCOUNT = REDIS_PROJECT_PREFIX + "LOGIN_ACCOUNT";

    public static final int REDIS_DEFAULT_EXPRIE_TIME = 30 * 60;
    /**
     * 限定这个 Realm 只处理 UsernamePasswordToken
     */
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof LoginToken;
    }

    /**
     * 查询数据库，将获取到的用户安全数据封装返回
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        LoginToken token = (LoginToken) authenticationToken;
        String username = token.getUsername();
        String password = new String((char[]) authenticationToken.getCredentials());
        String redisLoginAccountKey = StringUtils.joinWith(SYMBOL_UNDERLINE, REDIS_KEY_PREFIX_LOGIN_ACCOUNT, username);

        //查询是否存在当前用户，有效用户查询结果只能为1
        SysUser user = loginService.getUserByNameAndPwd(username, password);
        if(user == null){
            throw new AuthException(LOGIN_PWD_ERROR.getCode(), "登录验证失败, 用户名或密码错误");
        }
        // 缓存当前登录用户信息
        JwtEntity jwtEntity = new JwtEntity(user.getLoginId(), username, password, IdGenerator.getInstance().generateString());
        redisUtil.setex(redisLoginAccountKey, REDIS_DEFAULT_EXPRIE_TIME, JSON.toJSONString(jwtEntity));
        return new SimpleAuthenticationInfo(jwtEntity, password, getName());
    }


}